using Lzfy_His_Service.Models;

namespace Lzfy_His_Service.Services
{
    /// <summary>
    /// Senparc企业微信服务接口
    /// </summary>
    public interface ISenparcWeChatService
    {
        /// <summary>
        /// 获取企业微信授权URL
        /// </summary>
        /// <param name="redirectUri">重定向URI</param>
        /// <param name="state">状态参数</param>
        /// <returns>授权URL</returns>
        Task<string> GetAuthUrlAsync(string? redirectUri = null, string? state = null);

        /// <summary>
        /// 通过授权码获取用户信息
        /// </summary>
        /// <param name="code">授权码</param>
        /// <returns>用户信息</returns>
        Task<WeChatUserInfoResult> GetUserInfoAsync(string code);

        /// <summary>
        /// 获取成员详细信息
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>成员信息</returns>
        Task<WeChatMemberInfo> GetMemberInfoAsync(string userId);

        /// <summary>
        /// 验证企业微信签名
        /// </summary>
        /// <param name="signature">签名</param>
        /// <param name="timestamp">时间戳</param>
        /// <param name="nonce">随机数</param>
        /// <param name="echostr">随机字符串</param>
        /// <returns>验证结果</returns>
        Task<bool> ValidateSignatureAsync(string signature, string timestamp, string nonce, string? echostr = null);

        /// <summary>
        /// 获取JS-SDK配置
        /// </summary>
        /// <param name="url">当前页面URL</param>
        /// <returns>JS-SDK配置</returns>
        Task<JsApiConfig> GetJsApiConfigAsync(string url);

        /// <summary>
        /// 发送企业微信消息
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="message">消息内容</param>
        /// <returns>发送结果</returns>
        Task<SendMessageResult> SendMessageAsync(string userId, string message);

        /// <summary>
        /// 获取AccessToken
        /// </summary>
        /// <returns>AccessToken</returns>
        Task<string> GetAccessTokenAsync();

        /// <summary>
        /// 获取JsApiTicket
        /// </summary>
        /// <returns>JsApiTicket</returns>
        Task<string> GetJsApiTicketAsync();

        /// <summary>
        /// 刷新AccessToken
        /// </summary>
        /// <returns>新的AccessToken</returns>
        Task<string> RefreshAccessTokenAsync();

        /// <summary>
        /// 刷新JsApiTicket
        /// </summary>
        /// <returns>新的JsApiTicket</returns>
        Task<string> RefreshJsApiTicketAsync();

        /// <summary>
        /// 验证配置是否有效
        /// </summary>
        /// <returns>验证结果</returns>
        Task<bool> ValidateConfigurationAsync();
    }

    /// <summary>
    /// Senparc缓存服务接口
    /// </summary>
    public interface ISenparcCacheService
    {
        /// <summary>
        /// 获取AccessToken缓存
        /// </summary>
        /// <returns>AccessToken缓存信息</returns>
        Task<AccessTokenCache?> GetAccessTokenCacheAsync();

        /// <summary>
        /// 设置AccessToken缓存
        /// </summary>
        /// <param name="accessToken">AccessToken</param>
        /// <param name="expiresIn">过期时间（秒）</param>
        /// <returns>设置结果</returns>
        Task<bool> SetAccessTokenCacheAsync(string accessToken, int expiresIn);

        /// <summary>
        /// 获取JsApiTicket缓存
        /// </summary>
        /// <returns>JsApiTicket缓存信息</returns>
        Task<JsApiTicketCache?> GetJsApiTicketCacheAsync();

        /// <summary>
        /// 设置JsApiTicket缓存
        /// </summary>
        /// <param name="ticket">JsApiTicket</param>
        /// <param name="expiresIn">过期时间（秒）</param>
        /// <returns>设置结果</returns>
        Task<bool> SetJsApiTicketCacheAsync(string ticket, int expiresIn);

        /// <summary>
        /// 获取用户信息缓存
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>用户信息缓存</returns>
        Task<UserInfoCache?> GetUserInfoCacheAsync(string userId);

        /// <summary>
        /// 设置用户信息缓存
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="userInfo">用户信息</param>
        /// <returns>设置结果</returns>
        Task<bool> SetUserInfoCacheAsync(string userId, WeChatMemberInfo userInfo);

        /// <summary>
        /// 清除AccessToken缓存
        /// </summary>
        /// <returns>清除结果</returns>
        Task<bool> ClearAccessTokenCacheAsync();

        /// <summary>
        /// 清除JsApiTicket缓存
        /// </summary>
        /// <returns>清除结果</returns>
        Task<bool> ClearJsApiTicketCacheAsync();

        /// <summary>
        /// 清除用户信息缓存
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>清除结果</returns>
        Task<bool> ClearUserInfoCacheAsync(string userId);

        /// <summary>
        /// 清除所有缓存
        /// </summary>
        /// <returns>清除结果</returns>
        Task<bool> ClearAllCacheAsync();

        /// <summary>
        /// 生成缓存键
        /// </summary>
        /// <param name="key">键名</param>
        /// <returns>完整的缓存键</returns>
        string GenerateCacheKey(string key);
    }

    /// <summary>
    /// 认证服务扩展接口
    /// </summary>
    public interface IAuthService
    {
        /// <summary>
        /// 企业微信登录
        /// </summary>
        /// <param name="userLoginInfo">用户登录信息</param>
        /// <returns>登录结果</returns>
        Task<AuthServiceLoginResult> WeChatLoginAsync(UserLoginInfo userLoginInfo);

        /// <summary>
        /// 验证Token
        /// </summary>
        /// <param name="token">访问令牌</param>
        /// <returns>验证结果</returns>
        Task<bool> ValidateTokenAsync(string token);

        /// <summary>
        /// 刷新Token
        /// </summary>
        /// <param name="refreshToken">刷新令牌</param>
        /// <returns>新的Token信息</returns>
        Task<AuthServiceLoginResult> RefreshTokenAsync(string refreshToken);

        /// <summary>
        /// 用户登出
        /// </summary>
        /// <param name="token">访问令牌</param>
        /// <returns>登出结果</returns>
        Task<bool> LogoutAsync(string token);

        /// <summary>
        /// 获取当前用户信息
        /// </summary>
        /// <param name="token">访问令牌</param>
        /// <returns>用户信息</returns>
        Task<UserInfo?> GetCurrentUserAsync(string token);
    }
}